﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Entidades.Seguridad;
using Entidades.Sistema.Base;
using Entidades.Sistema.Venta;
using Entidades.Sistema.Produccion;
using Modelo.Sistema.Produccion;
using Modelo.Sistema.Venta;
using Modelo.Sistema.Base;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.Mvc;
using DevExpress.XtraPrinting.InternalAccess;
using DevExpress.XtraReports.UI;
using VistaOnlineR1._1.Models.Produccion;


namespace VistaOnlineR1._1.Controllers.Sistema.Produccion
{
    public class DiagramacionProduccionController : BaseController
    {
        #region campos
        CatalogoDiagramacionProduccion _catalogoDiagramacionProduccion;
        CatalogoPedidos _catalogoPedidos;
        CatalogoReceta _catagoloReceta;
        CatalogoEmpleado _catalogoEmpleado;
        CatalogoProductos _catalogoProductos;
        CatalogoInsumo _catalogoInsumo;
        public object CheckedValues { get; set; }
        #endregion 

        #region Constructors
        public DiagramacionProduccionController()
            : this( new CatalogoDiagramacionProduccion(), 
                    new CatalogoPedidos(), 
                    new CatalogoReceta(),
                    new CatalogoEmpleado(),
                    new CatalogoProductos(),
                    new CatalogoInsumo()
            )
        {
        }

        public DiagramacionProduccionController(CatalogoDiagramacionProduccion catalogoDiagramacionProduccion, 
                                                    CatalogoPedidos catalogoPedidos, 
                                                    CatalogoReceta catalogoReceta,
                                                    CatalogoEmpleado catalogoEmpleado,
                                                    CatalogoProductos catalogoProductos,
                                                    CatalogoInsumo catalogoInsumo
            )
        {
            _catalogoDiagramacionProduccion = catalogoDiagramacionProduccion;
            _catalogoPedidos = catalogoPedidos;
            _catagoloReceta = catalogoReceta;
            _catalogoEmpleado = catalogoEmpleado;
            _catalogoProductos = catalogoProductos;
            _catalogoInsumo = catalogoInsumo;    
        }
        #endregion

        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            base.Initialize(requestContext);
        }

        public ActionResult Index()
        {
            List<Perfil> perfiles = RecuperarPerfil();

            ViewBag.PermisoDelete = perfiles.Exists(per => per.Permiso.Nombre == "Delete");
            ViewBag.PermisoCreate = perfiles.Exists(per => per.Permiso.Nombre == "Create");
            ViewBag.PermisoEdit = perfiles.Exists(per => per.Permiso.Nombre == "Edit");
            ViewBag.PermisosConfirmar = true;

            return View(_catalogoDiagramacionProduccion.ListarDiagramacionProduccion().OrderByDescending(x => x.IdDiagramacionProduccion));
        }

        [ValidateInput(false)]
        public ActionResult EditDiagramacionProduccionPartial()
        {
            List<Perfil> perfiles = RecuperarPerfil();

            ViewBag.PermisoDelete = perfiles.Exists(per => per.Permiso.Nombre == "Delete");
            ViewBag.PermisoCreate = perfiles.Exists(per => per.Permiso.Nombre == "Create");
            ViewBag.PermisoEdit = perfiles.Exists(per => per.Permiso.Nombre == "Edit");
            ViewBag.PermisosConfirmar = true;

            return PartialView("EditDiagramacionProduccionPartial", _catalogoDiagramacionProduccion.ListarDiagramacionProduccion().OrderByDescending(x => x.IdDiagramacionProduccion));
        }

        [HttpGet]
        public ActionResult EditDiagramacionProduccionUpdatePartial(int IdDiagramacionProduccion)
        {
            DiagramacionProduccion editDiagramacionProduccio = new DiagramacionProduccion();
            
            if (IdDiagramacionProduccion == -1)
            {    
                ViewBag.TabInicio = true;
                ViewBag.TabPedidos = false;
                ViewBag.TabConfiguracion = false;
                ViewBag.TabResutado = false;
                editDiagramacionProduccio.IdDiagramacionProduccion = -1;
                editDiagramacionProduccio.Fecha = DateTime.Now;
                editDiagramacionProduccio.Estado = new DiagramacionEstadoCreada(editDiagramacionProduccio);
            }
            else
            {
                ViewBag.TabInicio = false;
                ViewBag.TabPedidos = true;
                ViewBag.TabConfiguracion = false;
                ViewBag.TabResutado = false;
                ViewBag.NoExistenPedidos = true;
                ViewBag.CheckActualizarAsignacion = true;

                editDiagramacionProduccio = _catalogoDiagramacionProduccion.BuscarDiagramacionProduccion(IdDiagramacionProduccion);

                List<Pedido> pedidos =
                    _catalogoPedidos.ListarPedidos().Where(x => x.FechaEntrega.Date == editDiagramacionProduccio.Fecha.Date && (x.Estado == PedidosEstado.Creado || x.Estado == PedidosEstado.ParcDiagramado || x.Estado == PedidosEstado.Diagramado)).ToList();

                editDiagramacionProduccio.Pedidos.Clear();
                foreach (Pedido pedido in pedidos)
                {
                    editDiagramacionProduccio.AgregarPedido(pedido);
                }

                foreach (Pedido ped in pedidos)
                {
                    //CheckedValues += string.Format("Pedido[{0}] - Cliente: {1};", ped.IdPedido.ToString(), ped.Cliente.Nombre);

                    foreach (DetallePedido det in ped.DetallePedidos.Where(x => x.Estado == StatesDetalle.Diagramado))
                    {
                        CheckedValues += string.Format("Detalle[{0}|{1}] - Producto: {2} - Cantidad: {3};", ped.IdPedido.ToString(), det.IdDetallePedido.ToString(), det.Producto.Nombre, det.Cantidad.ToString());
                    };
                };
                ViewBag.Pedidos = CheckedValues;
                string idsession = "DiagramacionProduccion";
                System.Web.HttpContext.Current.Session[idsession] = editDiagramacionProduccio;
            }

            return View("EditingFormTab", editDiagramacionProduccio);
        }

        public ActionResult CancelDiagramacionProduccionUpdatePartial(int IdDiagramacionProduccion)
        {
            List<Perfil> perfiles = RecuperarPerfil();

            ViewBag.PermisoDelete = perfiles.Exists(per => per.Permiso.Nombre == "Delete");
            ViewBag.PermisoCreate = perfiles.Exists(per => per.Permiso.Nombre == "Create");
            ViewBag.PermisoEdit = perfiles.Exists(per => per.Permiso.Nombre == "Edit");
            ViewBag.PermisosConfirmar = true;

            if (IdDiagramacionProduccion != -1)
            {
                foreach (Pedido p in _catalogoDiagramacionProduccion.BuscarDiagramacionProduccion(IdDiagramacionProduccion).Pedidos)
                {
                    _catalogoPedidos.CancelarEdicionPedido(p.IdPedido);
                }

                _catalogoDiagramacionProduccion.CancelarDiagramacionProduccion(IdDiagramacionProduccion);
            }

            return View("EditDiagramacionProduccionPartial", _catalogoDiagramacionProduccion.ListarDiagramacionProduccion().OrderByDescending(x => x.IdDiagramacionProduccion));
        }

        public ActionResult CambiaEstadoDiagramacionProduccionPartial(int IdDiagramacionProduccion)
        {
            DiagramacionProduccion editDiagramacionProduccio = new DiagramacionProduccion();
            editDiagramacionProduccio = _catalogoDiagramacionProduccion.BuscarDiagramacionProduccion(IdDiagramacionProduccion);
            string idsession = "DiagramacionProduccion";
            System.Web.HttpContext.Current.Session[idsession] = editDiagramacionProduccio;

            ViewBag.EstadosDisponibles = editDiagramacionProduccio.proximosEstados;
            if (editDiagramacionProduccio.proximosEstados.Count() > 0) { ViewBag.PermiteGuardar = true; } else { ViewBag.PermiteGuardar = false; }

            return View("EditingDiagramacionProduccion", editDiagramacionProduccio);
        }
        [HttpPost, ValidateInput(false)]
        public ActionResult CambiaEstadoDiagramacionProduccionPartial(DiagramacionProduccion editDiagramacionProduccio)
        {

            try
            {
                List<Perfil> perfiles = RecuperarPerfil();
                string estado = String.IsNullOrEmpty(Request.Params["idEstado"]) ? null : (Request.Params["idEstado"]);
            
                DiagramacionProduccion d = _catalogoDiagramacionProduccion.BuscarDiagramacionProduccion(editDiagramacionProduccio.IdDiagramacionProduccion);
                //d.Fecha = editDiagramacionProduccio.Fecha;
                d.Comentario = editDiagramacionProduccio.Comentario;

                List<Pedido> pedidos = _catalogoPedidos.ListarPedidos().Where(x => x.FechaEntrega.Date == d.Fecha.Date).ToList();
                foreach (Pedido p in pedidos)
                {
                    d.AgregarPedido(p);
                }

                //obtengo de la lista de los proximos estados el estado seleccionado del combobox del formulario.
                DiagramacionEstado e = (DiagramacionEstado)d.Estado.proximosEstados.FirstOrDefault(x => x.descrip == estado);            
                d.cambioEstado(e, d.Comentario);

                //actulizo los pedidos, obtengo el estado de los mismos según el estado de la diagramación.
                foreach (Pedido p in e.obtenerPedidos)
                {
                    _catalogoPedidos.ModificarPedido(p);
                }
                if (e.bajaStock)
                {
                    foreach (InsumoNecesario r in d.InsumosNecesarios)
                    {
                        Insumo oInsumo = _catalogoInsumo.ListarInsumos().FirstOrDefault(x => x.IdInsumo == r.Insumo.IdInsumo);
                        oInsumo.StockNecesario = oInsumo.StockNecesario - (int)r.Cantidad;
                        _catalogoInsumo.ModificarInsumo(oInsumo);
                    }
                }

                _catalogoDiagramacionProduccion.CambiarEstadoDiagramacionProduccion(d);

                ViewBag.PermisoDelete = perfiles.Exists(per => per.Permiso.Nombre == "Delete");
                ViewBag.PermisoCreate = perfiles.Exists(per => per.Permiso.Nombre == "Create");
                ViewBag.PermisoEdit = perfiles.Exists(per => per.Permiso.Nombre == "Edit");
                ViewBag.PermisosCambiarEstado = true; //Todo- agregar el perfil para cambiar el estado.

            }
            catch (Exception ex)
            {
                throw (ex);
            }

            return View("EditDiagramacionProduccionPartial",_catalogoDiagramacionProduccion.ListarDiagramacionProduccion().OrderByDescending(x => x.IdDiagramacionProduccion));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult PostInicioPartial(DiagramacionProduccion DiagramacionProduccion)
        {
            ViewBag.TabInicio = false;
            ViewBag.TabPedidos = true;
            ViewBag.TabConfiguracion = false;
            ViewBag.TabResutado = false;
            ViewBag.NoExistenPedidos = true;

            if (_catalogoDiagramacionProduccion.ListarDiagramacionProduccion().Any(x => x.Fecha.Date == DiagramacionProduccion.Fecha.Date && x.Estado.idEstado != (short)EnumEstados.Cancelada))
            {
                ViewBag.TabInicio = true;
                ViewBag.TabPedidos = false;
                ViewBag.TabConfiguracion = false;
                ViewBag.TabResutado = false;
                
                ViewBag.Message = "Ya existe una digramación de produccion para la fecha seleccionada.";
                
                return View("EditingFormTab", DiagramacionProduccion);
            }

            //Reviasr los casos que son parcialmente diagramados
            List<Pedido> pedidos = _catalogoPedidos.ListarPedidos().Where(x => x.FechaEntrega.Date == DiagramacionProduccion.Fecha.Date && x.Estado == PedidosEstado.Creado).ToList();
            ViewBag.Pedidos = pedidos;
            
            if (pedidos.Count == 0)
            {
                ViewBag.NoExistenPedidos = false;
                ViewBag.Message = "No se encontraron pedidos para la fecha selecciona.";
            }

            foreach (Pedido ped in pedidos)
            {
                DiagramacionProduccion.AgregarPedido(ped);
            }

            string idsession = "DiagramacionProduccion";
            System.Web.HttpContext.Current.Session[idsession] = DiagramacionProduccion;

            return View("EditingFormTab", DiagramacionProduccion);
        }
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult PostPedidosPartial(DiagramacionProduccion DiagramacionProduccion)
        {
            string idsession = "DiagramacionProduccion";
            DiagramacionProduccion diagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];

            CheckedValues = Request.Params["hf"];
            string[] pedidosdetalle = CheckedValues.ToString().Split(';');
            List<Pedido> pedidos = new List<Pedido>();

            //Inicializo el estado de los pedidos
            if (DiagramacionProduccion.IdDiagramacionProduccion != -1)
            {
                foreach (Pedido ped in diagramacionProduccion.Pedidos)
                {
                    diagramacionProduccion.Pedidos.FirstOrDefault(x => x.IdPedido == ped.IdPedido).Estado = PedidosEstado.Creado;
                    foreach (DetallePedido det in ped.DetallePedidos)
                    {
                        diagramacionProduccion.Pedidos.FirstOrDefault(x => x.IdPedido == ped.IdPedido).DetallePedidos.FirstOrDefault(y => y.IdDetallePedido == det.IdDetallePedido).Estado = StatesDetalle.PendienteDiagramacion;
                    }
                }
            }

            bool validarPedido = false;

            foreach (string peddet in pedidosdetalle)
            {
                if (peddet.StartsWith("Detalle"))
                {
                    validarPedido = true;
                    int ini = peddet.IndexOf("[") + 1;
                    int medio = peddet.IndexOf("|", ini);
                    int final = peddet.IndexOf("]", medio);
                    string idPedido = peddet.Substring(ini, medio - ini);
                    string idDetalle = peddet.Substring(medio + 1, final - (medio + 1));

                    diagramacionProduccion.Pedidos.FirstOrDefault(x => x.IdPedido == Convert.ToInt16(idPedido)).DetallePedidos.FirstOrDefault(x => x.IdDetallePedido == Convert.ToInt16(idDetalle)).Estado = StatesDetalle.Diagramado;                    
                }
            }

            if (!validarPedido)
            {
                ViewBag.NoExistenPedidos = true;
                ViewBag.CheckActualizarAsignacion = true;
                ViewBag.TabInicio = false;
                ViewBag.TabPedidos = true;
                ViewBag.TabConfiguracion = false;
                ViewBag.TabResutado = false;

                List<Pedido> pedidoss = _catalogoPedidos.ListarPedidos().Where(x => x.FechaEntrega.Date == DiagramacionProduccion.Fecha.Date && x.Estado == PedidosEstado.Creado).ToList();
                ViewBag.Pedidos = pedidoss;
                ViewBag.Message = "No se selecciono ningún pedido.";

                System.Web.HttpContext.Current.Session[idsession] = diagramacionProduccion;

                return View("EditingFormTab", diagramacionProduccion);
            }

            List<ProduccionProducto> produccionproducto = new List<ProduccionProducto>();
            //Se generan los productos a producir
            foreach (Pedido ped in diagramacionProduccion.Pedidos)
            {
                foreach (DetallePedido det in ped.DetallePedidos.Where(x => x.Estado == StatesDetalle.Diagramado))
                {
                    if (produccionproducto.Any(x => x.Producto.IdProducto == det.Producto.IdProducto))
                    {
                        produccionproducto.FirstOrDefault(x => x.Producto.IdProducto == det.Producto.IdProducto).CantidadDemanda =
                        produccionproducto.FirstOrDefault(x => x.Producto.IdProducto == det.Producto.IdProducto).CantidadDemanda + det.Cantidad;
                    }
                    else
                    {
                        ProduccionProducto oProduccionProducto = new ProduccionProducto(det.Producto, det.Cantidad);
                        produccionproducto.Add(oProduccionProducto);
                    }
                }
            }

            //List<Empleado> empleados = _catalogoEmpleado.Listarempleados().Where(x => x.Cargo.HabilitadoProduccion == true).ToList();
            //Todo- revisar si podemos hacerlo directamente sobre la actualización de la diagramacion.
            List<ProduccionProducto> produccionproductosactuales = new List<ProduccionProducto>();
            foreach (ProduccionProducto pp in diagramacionProduccion.ProduccionProductos)
            {
                produccionproductosactuales.Add(pp);
            }
                
            diagramacionProduccion.ProduccionProductos.Clear();
            //Todo- Existe produccion sin empleados asignados o es insuficente para completar la produccion.
            foreach(ProduccionProducto prod in produccionproducto)
            {
                //En caso de ser una actulizacion de la diagramacion consulto los datos existentes sobre las cantidad exdentes.
                //Todo- si ingresamos por el if deberiamos agregar los empleados existente en la diagramacion existete.
                //if (diagramacionProduccion.IdDiagramacionProduccion == -1 || (diagramacionProduccion.IdDiagramacionProduccion != -1 && calcularProduccion == "C"))
                if (diagramacionProduccion.IdDiagramacionProduccion != -1)
                {
                    if (produccionproductosactuales.Any(x => x.Producto.IdProducto == prod.Producto.IdProducto))
                        prod.CantidadExedente = produccionproductosactuales.FirstOrDefault(x => x.Producto.IdProducto == prod.Producto.IdProducto).CantidadExedente;

                    if (produccionproductosactuales.Any(x => x.Producto.IdProducto == prod.Producto.IdProducto))
                    {
                        foreach (ProduccionProductoDetalle d in produccionproductosactuales.FirstOrDefault(x => x.Producto.IdProducto == prod.Producto.IdProducto).Detalle)
                        {
                            prod.AgregarDetalle(d);
                        }                    
                    }                    
                }
                diagramacionProduccion.AgregarDetalle(prod);
            }

            System.Web.HttpContext.Current.Session[idsession] = diagramacionProduccion;

            ViewBag.TabInicio = false;
            ViewBag.TabPedidos = false;
            ViewBag.TabConfiguracion = true;
            ViewBag.TabResutado = false;

            return View("EditingFormTab", diagramacionProduccion);
        }        
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult PostConfiguracionPartial(DiagramacionProduccion DiagramacionProduccion)
        {
            //Esto es para poder persistir luego al finalizar la digramacion
            string idsession = "DiagramacionProduccion";
            DiagramacionProduccion diagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];
            ViewBag.Empleado = _catalogoEmpleado.Listarempleados().Where(x => x.Cargo.HabilitadoProduccion == true).ToList();

            if (diagramacionProduccion != null)
            {
               if (diagramacionProduccion.IdDiagramacionProduccion == -1)
               {
                   diagramacionProduccion.Estado = new DiagramacionEstadoCreada(diagramacionProduccion);
                   int ret = _catalogoDiagramacionProduccion.AgregarDiagramacionProduccion(diagramacionProduccion);                   
               }
               else
               {
                   foreach (InsumoNecesario r in diagramacionProduccion.InsumosNecesarios)
                   {
                       Insumo oInsumo = _catalogoInsumo.ListarInsumos().FirstOrDefault(x => x.IdInsumo == r.Insumo.IdInsumo);
                       oInsumo.StockNecesario = oInsumo.StockNecesario - (int)r.Cantidad;
                       _catalogoInsumo.ModificarInsumo(oInsumo);
                   }

                   diagramacionProduccion.Estado = new DiagramacionEstadoEditada(diagramacionProduccion);
                   _catalogoDiagramacionProduccion.ModificarDiagramacionProduccion(diagramacionProduccion);
               }

               diagramacionProduccion.InsumosNecesarios.Clear();
               foreach (ProduccionProducto produccionproducto in diagramacionProduccion.ProduccionProductos)
               {
                   if (produccionproducto.Receta != null)
                   {
                       Receta oReceta = new Receta();
                       oReceta = _catagoloReceta.ListarRecetas().FirstOrDefault(x => x.Producto.IdProducto == produccionproducto.Producto.IdProducto && x.Predeterminada == true);
                       if (oReceta != null)
                       {
                           foreach (RecetaDetalle recetadetalle in oReceta.RecetaDetalles)
                           {
                               if (diagramacionProduccion.InsumosNecesarios.Count > 0 && diagramacionProduccion.InsumosNecesarios.Any(x => x.Insumo.IdInsumo == recetadetalle.Insumo.IdInsumo))
                               {
                                   diagramacionProduccion.InsumosNecesarios.FirstOrDefault(x => x.Insumo.IdInsumo == recetadetalle.Insumo.IdInsumo).Cantidad =
                                       diagramacionProduccion.InsumosNecesarios.FirstOrDefault(x => x.Insumo.IdInsumo == recetadetalle.Insumo.IdInsumo).Cantidad + (recetadetalle.Cantidad * produccionproducto.Total);
                               }
                               else
                               {
                                   InsumoNecesario insumoncesario = new InsumoNecesario();
                                   insumoncesario.Cantidad = recetadetalle.Cantidad * produccionproducto.Total;
                                   insumoncesario.Insumo = recetadetalle.Insumo;
                                   insumoncesario.IdInsumoNecesario = recetadetalle.Insumo.IdInsumo;
                                   diagramacionProduccion.InsumosNecesarios.Add(insumoncesario);
                               }
                           }
                       }                       
                   }
               }

               foreach (InsumoNecesario r in diagramacionProduccion.InsumosNecesarios)
               {
                   Insumo oInsumo = _catalogoInsumo.ListarInsumos().FirstOrDefault(x => x.IdInsumo == r.Insumo.IdInsumo);
                   oInsumo.StockNecesario = oInsumo.StockNecesario + (int)r.Cantidad;
                   _catalogoInsumo.ModificarInsumo(oInsumo);
               }

               foreach (Pedido oPedido in diagramacionProduccion.Pedidos)
               {
                   int cantReng = oPedido.DetallePedidos.Count();
                   int cantPend = oPedido.DetallePedidos.Count(x => x.Estado == StatesDetalle.PendienteDiagramacion);
                   int cantDiag = oPedido.DetallePedidos.Count(x => x.Estado == StatesDetalle.Diagramado);

                   if (cantReng == cantPend)
                   {
                       oPedido.Estado = PedidosEstado.Creado;
                   }
                   else if (cantReng == cantDiag)
                   {
                       oPedido.Estado = PedidosEstado.Diagramado;
                   }
                   else
                   {
                       oPedido.Estado = PedidosEstado.ParcDiagramado;
                   }
                   _catalogoPedidos.ModificarPedido(oPedido);
               }
            }

            System.Web.HttpContext.Current.Session.Remove(idsession);

            ViewBag.TabInicio = false;
            ViewBag.TabPedidos = false;
            ViewBag.TabConfiguracion = false;
            ViewBag.TabResutado = true;

            return View("EditingFormTab", diagramacionProduccion);
        }

        [HttpGet]
        public ActionResult EditDiagramacionProduccionConfirmarPartial(int IdDiagramacionProduccion)
        {

            List<Perfil> perfiles = RecuperarPerfil();

            ViewBag.PermisoDelete = perfiles.Exists(per => per.Permiso.Nombre == "Delete");
            ViewBag.PermisoCreate = perfiles.Exists(per => per.Permiso.Nombre == "Create");
            ViewBag.PermisoEdit = perfiles.Exists(per => per.Permiso.Nombre == "Edit");
            ViewBag.PermisosConfirmar = true;

            DiagramacionProduccion diagramacion = _catalogoDiagramacionProduccion.BuscarDiagramacionProduccion(IdDiagramacionProduccion);
            diagramacion.cambioEstado(new DiagramacionEstadoFinalizada(diagramacion), "La diagramacion finalizo correctamente");
            diagramacion.ProduccionProductos.Clear();

            _catalogoDiagramacionProduccion.ModificarDiagramacionProduccion(diagramacion);

            List<Pedido> pedidos = _catalogoPedidos.ListarPedidos().Where(x => x.FechaEntrega.Date == diagramacion.Fecha.Date).ToList();
            foreach (Pedido p in pedidos)
            {
                pedidos.FirstOrDefault(x => x.IdPedido == p.IdPedido).Estado = PedidosEstado.Creado;
                foreach (DetallePedido d in p.DetallePedidos)
                {
                    pedidos.FirstOrDefault(x => x.IdPedido == p.IdPedido).DetallePedidos.FirstOrDefault(y => y.IdDetallePedido == d.IdDetallePedido).Estado = StatesDetalle.Producido;
                }
            }

            return View("EditDiagramacionProduccionPartial", _catalogoDiagramacionProduccion.ListarDiagramacionProduccion().OrderByDescending(x => x.IdDiagramacionProduccion));
        }

        public ActionResult EditProduccionProductosPartial()
        {
            string idsession = "DiagramacionProduccion";
            DiagramacionProduccion diagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];
            ViewBag.Empleado = _catalogoEmpleado.Listarempleados().Where(x => x.Cargo.HabilitadoProduccion == true).ToList();
            return PartialView("EditProduccionProductosPartial", diagramacionProduccion.ProduccionProductos);
        }
        public ActionResult EditProduccionProductosUpdatePartial(MVCxGridViewBatchUpdateValues<ProduccionProducto, int> updateValues)
        {
            string idsession = "DiagramacionProduccion";
            DiagramacionProduccion diagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];

            foreach (ProduccionProducto produccionproducto in updateValues.Update) {
                
                //Actualizo la cantida exedente
                diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == produccionproducto.IdProduccionProducto).CantidadExedente = produccionproducto.CantidadExedente;
                int total = diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == produccionproducto.IdProduccionProducto).Total;               
            }

            System.Web.HttpContext.Current.Session[idsession] = diagramacionProduccion;

            return PartialView("EditProduccionProductosPartial", diagramacionProduccion.ProduccionProductos);
        }

        public ActionResult EditProduccionProductosDetalleUpdatePartial(MVCxGridViewBatchUpdateValues<ProduccionProductoDetalle, int> updateValues, int IdProduccionProducto)
        {
            string idsession = "DiagramacionProduccion";
            DiagramacionProduccion diagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];
            ViewData["IdProduccionProducto"] = IdProduccionProducto;

            foreach (ProduccionProductoDetalle det in updateValues.Insert)
            {
                Empleado e = _catalogoEmpleado.Listarempleados().FirstOrDefault(x => x.IdEmpleado == det.Empleado.IdEmpleado);
                det.Empleado = e;
                if (!diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Detalle.Any(y => y.Empleado.IdEmpleado == e.IdEmpleado))
                {
                    if (det.CantidadProducir != 0)
                    {
                        diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).AgregarDetalle(det);
                    }
                    else
                        ViewData["EditError"] = string.Format("No se ingreso cantidad a producir");
                }
                else
                    ViewData["EditError"] = string.Format("El empleado {0} ya se encuentra asignado", det.Empleado.NombreApellido);

            }
            foreach (ProduccionProductoDetalle det in updateValues.Update)
            {
                Empleado e = _catalogoEmpleado.Listarempleados().FirstOrDefault(x => x.IdEmpleado == Convert.ToInt32(det.Empleado.IdEmpleado));
                det.Empleado = e;
                diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Detalle.FirstOrDefault(y => y.Empleado.IdEmpleado == e.IdEmpleado).CantidadProducir = det.CantidadProducir;
            }
            foreach (int id in updateValues.DeleteKeys)
            {               
                diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).EliminarDetalle(diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Detalle.FirstOrDefault(y => y.Empleado.IdEmpleado == id));
            }
            if (diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Total <
                diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).TotalAProducir)
            {
                ViewData["EditError"] = string.Format("La cantidad asignada para producir({0}) es mayor a la cantidad requerida({1}).",diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).TotalAProducir.ToString(),diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Total.ToString());
            }
            if (diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Total >
                diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).TotalAProducir)
            {
                ViewData["EditError"] = string.Format("La cantidad requerida({0}) es mayor a la cantidad a producir({1}).", diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Total.ToString(), diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).TotalAProducir.ToString());
            }

            System.Web.HttpContext.Current.Session[idsession] = diagramacionProduccion;
            ViewBag.Empleado = _catalogoEmpleado.Listarempleados().Where(x => x.Cargo.HabilitadoProduccion == true).ToList();

            return PartialView("EditProduccionProductosDetallePartial", diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Detalle);
        }
        public ActionResult EditProduccionProductosDetallePartial(int IdProduccionProducto)
        {
            string idsession = "DiagramacionProduccion";
            DiagramacionProduccion diagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];
            ViewData["IdProduccionProducto"] = IdProduccionProducto;
            ViewBag.Empleado = _catalogoEmpleado.Listarempleados().Where(x => x.Cargo.HabilitadoProduccion == true).ToList();
            //ViewBag.MaxAProducir = diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Total;

            return PartialView("EditProduccionProductosDetallePartial", diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Detalle);
        }

        //Imprimir
        public ActionResult ImprimirDiagramacion(int IdDiagramacionProduccion)
        {
            string idsession = "DiagramacionAImprimir";
            DiagramacionProduccion oDiagramacionProduccion = new DiagramacionProduccion();
            oDiagramacionProduccion = _catalogoDiagramacionProduccion.BuscarDiagramacionProduccion(IdDiagramacionProduccion);
            System.Web.HttpContext.Current.Session[idsession] = oDiagramacionProduccion;
            return View();
        }
        public ActionResult ImprimirDiagramacionPartial()
        {
            string idsession = "DiagramacionAImprimir";
            string idsessionreporte = "Reporte";
            DiagramacionProduccion oDiagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];
            Reportes.rptDiagramacionProduccion rpt = new Reportes.rptDiagramacionProduccion();

            rpt.DataSource = _catalogoDiagramacionProduccion.ListarDiagramacionProduccion().Where(x => x.IdDiagramacionProduccion == oDiagramacionProduccion.IdDiagramacionProduccion).ToList();
            ViewData["Report"] = rpt;
            System.Web.HttpContext.Current.Session[idsessionreporte] = rpt;

            return PartialView("ImprimirDiagramacionPartial");
        }
        public ActionResult ImprimirDiagramacionPartialExportTo()
        {
            string idsessionreporte = "Reporte";
            Reportes.rptDiagramacionProduccion rpt = (Reportes.rptDiagramacionProduccion)System.Web.HttpContext.Current.Session[idsessionreporte];
            return DocumentViewerExtension.ExportTo(rpt);
        }

        public ActionResult ImprimirOrderDeTrabajo()
        {
            ViewBag.Message = "Imprimir order de trabajo!";
            ViewData["Empleados"] = _catalogoEmpleado.Listarempleados();

            DtoOrdenDeTrabajo ordendetrabajo = new DtoOrdenDeTrabajo();
            ordendetrabajo.Fecha = DateTime.Today;


            return View(ordendetrabajo);
        }
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult PostImprimirOrderDeTrabajo(DtoOrdenDeTrabajo ordendetrabajo)
        {
            if (ordendetrabajo.Fecha == null)
                return View("DiagramacionProduccion", "ImprimirOrderDeTrabajo", ordendetrabajo);

            string idsession = "OrdenDeTrabajo";
            string idsessionParametro = "Empleado";
            DiagramacionProduccion oDiagramacionProduccion = new DiagramacionProduccion();
            oDiagramacionProduccion = _catalogoDiagramacionProduccion.ListarDiagramacionProduccion().FirstOrDefault(x => x.Fecha.Date == ordendetrabajo.Fecha && x.Estado.idEstado != (short)EnumEstados.Cancelada);
            System.Web.HttpContext.Current.Session[idsession] = oDiagramacionProduccion;
            System.Web.HttpContext.Current.Session[idsessionParametro] = ordendetrabajo.empleado.IdEmpleado;
            return View();
        }
        public ActionResult ReportViewerPartial()
        {
            string idsession = "OrdenDeTrabajo";
            string idsessionParametro = "Empleado";
            string idsessionreporte = "Reporte";            
            DiagramacionProduccion oDiagramacionProduccion = (DiagramacionProduccion)System.Web.HttpContext.Current.Session[idsession];
            int idEmpleado = (int)System.Web.HttpContext.Current.Session[idsessionParametro];


            Reportes.rptOrdenDeTrabajo report;
            List<DtoOrdenDeTrabajo> list = new List<DtoOrdenDeTrabajo>();

            if (oDiagramacionProduccion != null)
            {
                foreach (ProduccionProducto pp in oDiagramacionProduccion.ProduccionProductos)
                {
                    foreach (ProduccionProductoDetalle ppd in pp.Detalle)
                    {
                        list.Add(new DtoOrdenDeTrabajo(pp.Producto, ppd.Empleado, ppd.CantidadProducir));
                    }
                }
                report = new Reportes.rptOrdenDeTrabajo(oDiagramacionProduccion.IdDiagramacionProduccion.ToString(), oDiagramacionProduccion.Fecha);
            }
            else
            {
                report = new Reportes.rptOrdenDeTrabajo("0", DateTime.Today);
            }

            if (idEmpleado != 0)
            {
                report.DataSource = list.Where(x => x.empleado.IdEmpleado == idEmpleado);
            }
            else
            {
                report.DataSource = list;
            }
            
            ViewData["Report"] = report;
            System.Web.HttpContext.Current.Session[idsessionreporte] = report;

            return PartialView("ReportViewerPartial");
        }

        public ActionResult ExportReportViewerPartial()
        {
            string idsessionreporte = "Reporte";
            Reportes.rptOrdenDeTrabajo rpt = (Reportes.rptOrdenDeTrabajo)System.Web.HttpContext.Current.Session[idsessionreporte];
            return DocumentViewerExtension.ExportTo(rpt);
        }


        private List<Empleado> ComboEmpleado(DiagramacionProduccion diagramacionProduccion, int IdProduccionProducto)
        {
            List<Empleado> empleados = new List<Empleado>();
            List<Empleado> empleadosdisponibles = new List<Empleado>();
            empleados = _catalogoEmpleado.Listarempleados().Where(x => x.Cargo.HabilitadoProduccion == true && x.Productos.Any(y => y.IdProducto == IdProduccionProducto)).ToList();

            foreach (ProduccionProductoDetalle produccionproductodetalle in diagramacionProduccion.ProduccionProductos.FirstOrDefault(x => x.IdProduccionProducto == IdProduccionProducto).Detalle)
            {
                empleados.RemoveAll(x => x.IdEmpleado == produccionproductodetalle.Empleado.IdEmpleado);
            }

            //Todo- Mejorar la busqueda de los emplados. Crear un metodo que devuelva los empleados asignados a la produccion con sus horas disponibles.
            //Solo listamos los empleados que no estan asignados al producto y los cuales tienen horas disponibles
            foreach (Empleado emp in empleados)
            {
                foreach (ProduccionProducto prod in diagramacionProduccion.ProduccionProductos)
                {
                    if (prod.Detalle.Any(x => x.Empleado.IdEmpleado == emp.IdEmpleado) && prod.Detalle.FirstOrDefault(x => x.Empleado.IdEmpleado == emp.IdEmpleado).Empleado.HorasDisponibles != 0)
                    {
                        if (!empleadosdisponibles.Any(x => x.IdEmpleado == emp.IdEmpleado))
                            empleadosdisponibles.Add(prod.Detalle.FirstOrDefault(x => x.Empleado.IdEmpleado == emp.IdEmpleado).Empleado);
                    }
                    else
                    {
                        empleadosdisponibles.Add(emp);
                    }

                }
            }

            return empleadosdisponibles;
        }
    }
}
